package com.querie.controller;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Map;

import com.querie.algorithms.FragmentRank;
import com.querie.algorithms.FragmentRankAbsolute;
import com.querie.algorithms.FragmentRankRelative;
import com.querie.dao.DAOFactory;
import com.querie.dao.QueryDAO;
import com.querie.dao.QueryDAOImpl;
import com.querie.dao.SessionfragmentDAO;
import com.querie.dao.SessionfragmentDAOImpl;
import com.querie.model.beans.Query;
import com.querie.model.beans.SessionFragment;
import com.querie.sql.ConnectionFactory;

public class FragmentRankController {

	public static void computeFragmentRank() {
		try {
			
			System.out.println("Fragment Ranking Starts");
			
			DAOFactory.getSessionfragmentDAO().deleteAll();
			Connection conn = ConnectionFactory.getConnection();
			
			ResultSet rs = null;
		    PreparedStatement stmt = null;
		    
			stmt = conn.prepareStatement("select * from query",ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
		    rs = stmt.executeQuery();
		    Query oQuery = new Query() ;
		    FragmentRank oFragmentRank = new FragmentRankAbsolute();
		    Map<Long,Double> hmFragmentRank = null;
		      
		    
		    while(rs.next()) {
		    	  oQuery.setSessionid(rs.getLong("sessionid"));
		    	  oQuery.setQueryid(rs.getLong("queryid"));
		    	  oQuery.setColumnfragid(rs.getString("columnfragid"));
		    	  oQuery.setTablefragid(rs.getString("tablefragid"));
		    	  oQuery.setWherefragid(rs.getString("wherefragid"));
		    	  oQuery.setGroupfragid(rs.getString("groupfragid"));
		    	  oQuery.setHavingfragid(rs.getString("havingfragid"));
		    	  oQuery.setOrderbyfragid(rs.getString("orderfragid"));
		    	  
		    	  
		    	  hmFragmentRank = oFragmentRank.getFragmentRank(oQuery);
		    	  
		    	  updateFragmentRankInDB(hmFragmentRank,oQuery);
		    	  
		    	  rs.updateString("queryfragmentimportance", oQuery.getQueryfragmentimportance());
		    	  rs.updateRow();
		    	  
		      }
		    
		    System.out.println("Fragment Ranking Finished");
		    
		    //conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
		}
		catch (Exception E) {
			E.printStackTrace();
			
		}
			 
		
	}
	
	
	private static void updateFragmentRankInDB(Map<Long, Double> hmFragmentRank, Query oQuery) throws Exception {
		// TODO Auto-generated method stub
		
		long sessionId = oQuery.getSessionid();
		
		
		SessionfragmentDAO oSessionfragmentDAO = new SessionfragmentDAOImpl();
		SessionFragment oSessionFragment = new SessionFragment();
		SessionFragment oSessionFragmentTemp = new SessionFragment();
		Iterator<Long> it = hmFragmentRank.keySet().iterator();
		long fragmentId;
		String sQuerySessionImportance = null;
		
		while(it.hasNext()) {
			fragmentId = it.next();
			oSessionFragment.setSessionid(sessionId);
			oSessionFragment.setFragmentid(fragmentId);
			oSessionFragment.setImportance(hmFragmentRank.get(fragmentId));
			
			if(sQuerySessionImportance != null) {
				sQuerySessionImportance += "::" + fragmentId +"," + oSessionFragment.getImportance();
			}
			else {
				sQuerySessionImportance = fragmentId +"," + oSessionFragment.getImportance();
			}
			
			//System.out.println(sQuerySessionImportance);
			oSessionFragmentTemp = oSessionfragmentDAO.load(sessionId, fragmentId);
			if ( oSessionFragmentTemp != null)
			{
				oSessionFragment.setImportance(oSessionFragment.getImportance() + oSessionFragmentTemp.getImportance());
				oSessionfragmentDAO.update(oSessionFragment);
			}
			else
			{
				oSessionfragmentDAO.insert(oSessionFragment);
			}
			
		}
		
		//System.out.println(sQuerySessionImportance);
		oQuery.setQueryfragmentimportance(sQuerySessionImportance);
		
	}
}
